package com.health.ts.service.sysmanage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.health.ts.constant.CustomPage;
import com.health.ts.constant.FrontPage;
import com.health.ts.constant.SysConstant;
import com.health.ts.dao.sysmanage.SysAuthorityMapper;
import com.health.ts.dao.sysmanage.SysMenuAuthorityMapper;
import com.health.ts.dao.sysmanage.SysMenuMapper;
import com.health.ts.dao.sysmanage.SysRoleAuthorityMapper;
import com.health.ts.dao.sysmanage.SysUserMapper;
import com.health.ts.entity.sysmanage.SysAuthority;
import com.health.ts.entity.sysmanage.SysMenu;
import com.health.ts.entity.sysmanage.SysMenuAuthority;
import com.health.ts.entity.sysmanage.SysRoleAuthority;
import com.health.ts.entity.sysmanage.SysUser;
import com.health.ts.entity.sysmanage.UserResetPwdReqVo;
import com.health.ts.service.BaseServiceImpl;
import com.health.ts.utils.AssertUtil;
import com.health.ts.utils.SessionUserUtil;
/**
 * 用户服务类
 * @author Administrator
 */
@Service
public class SysUserService extends BaseServiceImpl<SysUserMapper, SysUser> {
	
	/**
	 * 密码加密工具
	 */
	@Autowired
	BCryptPasswordEncoder passwordEncoder;
	
	@Autowired
	SysMenuMapper sysMenuMapper;
	
	@Autowired
	SysRoleAuthorityMapper sysRoleAuthorityMapper;
	
	@Autowired
	SysAuthorityMapper sysAuthorityMapper;
	
	@Autowired
	SysMenuAuthorityMapper sysMenuAuthorityMapper;
	
	/**
	 * 分页查询用户数据
	 * @param page
	 * @return
	 */
	public CustomPage<SysUser> findUserPageList(FrontPage page){
		QueryWrapper<SysUser> QueryWrapper = new QueryWrapper<SysUser>();
		QueryWrapper.eq("isSuper", "0");
		String hospital_id =getParam(page,"hospital_id");
		if (StringUtils.isNotEmpty(hospital_id)){
			QueryWrapper.eq("hospital_id", hospital_id); 
		}
		
		String department_id =getParam(page,"department_id");
		if (StringUtils.isNotEmpty(department_id)){
			QueryWrapper.eq("department_id", department_id); 
		}
		
		String user_name =getParam(page,"user_name");
		if (StringUtils.isNotEmpty(user_name)){
			QueryWrapper.like("user_name", user_name); 
		}
		
		//医院管理员只返回自己医院业务用户列表
		if(SessionUserUtil.userIsHosAdmin()){
			QueryWrapper.eq("hospital_id", SessionUserUtil.getUserHosId());
			QueryWrapper.eq("user_type", "3");
		}
		
		QueryWrapper.orderByDesc("update_time");
		
		Page<SysUser> pageList = this.page(page.getPagePlus(), QueryWrapper);
		for(SysUser user : pageList.getRecords()) {
			user.setPasswd(null);
		}
		return new CustomPage<SysUser>(pageList);
	}
	
	/**
	 * 查询用户列表(不带分页)
	 * @return
	 */
	public List<SysUser> findUserList(String hospital_id,String department_id){
		QueryWrapper<SysUser> QueryWrapper = new QueryWrapper<SysUser>();
		if(StringUtils.isNotEmpty(hospital_id)){
			QueryWrapper.eq("hospital_id", hospital_id);
		}
		if(StringUtils.isNotEmpty(department_id)){
			QueryWrapper.eq("department_id", department_id);
		}
		QueryWrapper.orderByDesc("update_time");
		List<SysUser> list=this.list(QueryWrapper);
		for(SysUser user : list) {
			user.setPasswd(null);
		}
		return list;
	}
	
	/**
	 * 获取单个用户
	 * @param id
	 * @return
	 */
	public SysUser findUserInfo(String userid){
		SysUser sysUser=this.getById(userid);
		AssertUtil.notNull(sysUser, "根据入参用户id没有查询到用户信息");
		// 数据库加密密码不返回
		sysUser.setPasswd(null);
		return sysUser;
	}
	
	/**
	 * 根据用户名查询用户方法
	 * @param username
	 * @return
	 */
	public SysUser selectUserByName(String username){
		QueryWrapper<SysUser> wrapper = new QueryWrapper<SysUser>();
		wrapper.eq("account_name", username);
		List<SysUser> list = this.list(wrapper);
		if(CollectionUtils.isNotEmpty(list)) {
			return  list.get(0);
		}
		return null;
	}
	
	/**
	 * 根据用户查询菜单列表
	 * @param sysUser
	 * @return
	 */
	public List<SysMenu> selectMenusByUser(SysUser sysUser){
		List<SysMenu> listMenu=new ArrayList<SysMenu>();//返回载体
		if(!"3".equals(sysUser.getUser_type())){
			QueryWrapper<SysMenu> menu_wrapper = new QueryWrapper<SysMenu>();
			menu_wrapper.eq("menu_classify", "1");
			List<SysMenu> listManageMenu = sysMenuMapper.selectList(menu_wrapper);
			listMenu.addAll(listManageMenu);
		}
		
		//超级管理员没有业务角色，不需获取业务菜单
		if(!"1".equals(sysUser.getIsSuper())){
			//获取用户业务菜单
			QueryWrapper<SysRoleAuthority> wrapper = new QueryWrapper<SysRoleAuthority>();
			if(StringUtils.isNotEmpty(sysUser.getRole_id())){
				wrapper.in("role_id", Arrays.asList(sysUser.getRole_id().split(","))); 
			}
			List<SysRoleAuthority> roleAuthorityList=sysRoleAuthorityMapper.selectList(wrapper);//查询角色关联的权限
			if(CollectionUtils.isNotEmpty(roleAuthorityList)) {
				//查询权限菜单
				List<String> authorityIds=roleAuthorityList.stream().map(SysRoleAuthority::getAuthority_id).collect(Collectors.toList());
				QueryWrapper<SysMenuAuthority> auth_wrapper = new QueryWrapper<SysMenuAuthority>();
				auth_wrapper.in("authority_id", authorityIds);
				List<SysMenuAuthority> listMenuAuthoritys=sysMenuAuthorityMapper.selectList(auth_wrapper);//当前权限的菜单数
				if(CollectionUtils.isNotEmpty(listMenuAuthoritys)) {
					//查询权限菜单
					List<String> menuIds=listMenuAuthoritys.stream().map(SysMenuAuthority::getMenu_id).collect(Collectors.toList());
					listMenu = sysMenuMapper.selectBatchIds(menuIds);
				}
			}
			//一级菜单有重复项 去重处理
			listMenu = new ArrayList<SysMenu>(new HashSet<SysMenu>(listMenu));
		}
		//排序
		listMenu.sort(Comparator.comparing(SysMenu::getMenu_order));
		return listMenu;
	}
	
	/**
	 * 根据用户查询用户权限列表
	 * @param sysUser
	 * @return
	 */
	public List<SysAuthority> selectAuthorityByUser(SysUser sysUser){
		if(StringUtils.isNotEmpty(sysUser.getRole_id())){
			//获取用户业务菜单
			QueryWrapper<SysRoleAuthority> wrapper = new QueryWrapper<SysRoleAuthority>();
			wrapper.in("role_id", Arrays.asList(sysUser.getRole_id().split(","))); 
			List<SysRoleAuthority> roleAuthorityList=sysRoleAuthorityMapper.selectList(wrapper);//查询角色关联的权限
			if(CollectionUtils.isNotEmpty(roleAuthorityList)) {
				//查询权限菜单
				List<String> authorityIds=roleAuthorityList.stream().map(SysRoleAuthority::getAuthority_id).collect(Collectors.toList());
				return sysAuthorityMapper.selectBatchIds(authorityIds);
			}
		}
		return Collections.emptyList();
	}
	
	/**
	 * 新增用户
	 * 
	 * @param reqVo
	 */
	@Transactional(rollbackFor = Exception.class)
	public void addUser(SysUser sysUser) {
		QueryWrapper<SysUser> userCodeQueryWrapper = new QueryWrapper<SysUser>();
		userCodeQueryWrapper.eq("user_code", sysUser.getUser_code());
		List<SysUser> checkUserCodeList = this.list(userCodeQueryWrapper);
		AssertUtil.empty(checkUserCodeList, "新增用户失败：用户编码【"+sysUser.getUser_code()+"】已存在！");
		
		QueryWrapper<SysUser> userAccountQueryWrapper = new QueryWrapper<SysUser>();
		userAccountQueryWrapper.eq("account_name", sysUser.getAccount_name());
		List<SysUser> checkUserAccountList = this.list(userAccountQueryWrapper);
		AssertUtil.empty(checkUserAccountList, "新增用户失败：用户账户【"+sysUser.getAccount_name()+"】已存在！");
		//执行新增
		Date now=new Date();
		sysUser.setCreate_time(now);
		sysUser.setUpdate_time(now);
		sysUser.setIsSuper("0");
		// 账号初始化密码统一为123456
		sysUser.setPasswd(passwordEncoder.encode(SysConstant.USER_INIT_PASSWORD));
		this.save(sysUser);
	}
	
	/**
	 * 修改用户
	 * 
	 * @param reqVo
	 */
	@Transactional(rollbackFor = Exception.class)
	public void updateUser(String userid, SysUser sysUser) {
		SysUser info = this.getById(userid);
		AssertUtil.notNull(info, "要修改的用户不存在！");
		sysUser.setId(userid);
		sysUser.setUpdate_time(new Date());
		sysUser.setPasswd(info.getPasswd());
		this.updateById(sysUser);
	}
	
	/**
	 * 重置用户密码
	 * 
	 * @param reqVo
	 */
	@Transactional(rollbackFor = Exception.class)
	public void resetUserPwd(UserResetPwdReqVo reqVo) {
		SysUser sessionUser = SessionUserUtil.getUser();
		AssertUtil.isTrue(reqVo.getNewPasswd().equals(reqVo.getConfirmNewPasswd()), "新密码和确认密码不一致，请重新填写");
		SysUser dbUser = this.getById(sessionUser.getId());
		AssertUtil.isTrue(passwordEncoder.matches(reqVo.getOldPasswd(), dbUser.getPasswd()), "原密码不正确，请重新填写");
		dbUser.setPasswd(passwordEncoder.encode(reqVo.getNewPasswd()));
		this.updateById(dbUser);
	}
}
